#region  == Copyright ==
// =====================================================================
//  Microsoft Consulting Services France - Aymeric Mouillé - 2013
//  Projet     : Solution Cmd Helper - Solution Cmd Helper
//  Fichier    : CommandArgs.cs (24/06/2013 21:49)
//  
//  Copyright (C) Microsoft Corporation.  All rights reserved.
// =====================================================================
#endregion

namespace Solution.Cmd.Helper
{
    #region  == Using ==
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Text;

    #endregion

    public class CommandArgs
    {
        #region Operation
        /// <summary>
        /// Gets or sets the operation to proceed
        /// </summary>
        /// <value>
        /// import, export, delete or publish
        /// </value>
        public string Operation { get; set; }
        #endregion

        #region Crm Connection String
        /// <summary>
        /// Gets or sets the CRM connection string.
        /// </summary>
        /// <value>
        /// The CRM connection string.
        /// </value>
        public string CrmConnectionString { get; set; }
        #endregion

        #region Solution Name
        /// <summary>
        /// Gets or sets the name of the solution.
        /// </summary>
        /// <value>
        /// The name of the solution.
        /// </value>
        public string SolutionName { get; set; }
        #endregion


        #region Application Log File Path
        /// <summary>
        /// Gets or sets the application log file path.
        /// </summary>
        /// <value>
        /// The log file path.
        /// </value>
        public string ApplicationLogFilePath { get; set; }
        #endregion


        #region Solution File Path
        /// <summary>
        /// Gets or sets the solution file path.
        /// </summary>
        /// <value>
        /// The solution file path.
        /// </value>
        public string SolutionFilePath { get; set; }
        #endregion

        #region Log File Path
        /// <summary>
        /// Gets or sets the log file path.
        /// </summary>
        /// <value>
        /// The log file path.
        /// </value>
        public string LogFilePath { get; set; }
        #endregion

        #region Confirm Prompt
        /// <summary>
        /// Gets or sets a value indicating whether [confirm prompt].
        /// </summary>
        /// <value>
        ///     <c>true</c> if [confirm prompt]; otherwise, <c>false</c>.
        /// </value>
        public bool ConfirmPrompt { get; set; }
        #endregion

        #region No Prompt
        /// <summary>
        /// Gets or sets a value indicating whether [no prompt].
        /// </summary>
        /// <value>
        ///   <c>true</c> if [no prompt]; otherwise, <c>false</c>.
        /// </value>
        public bool NoPrompt { get; set; }
        #endregion

        #region Hide Header
        /// <summary>
        /// Gets or sets a value indicating whether [hide header].
        /// </summary>
        /// <value>
        ///   <c>true</c> if [hide header]; otherwise, <c>false</c>.
        /// </value>
        public bool HideHeader { get; set; }
        #endregion

        #region Managed
        /// <summary>
        /// Gets or sets the managed.
        /// </summary>
        /// <value>
        /// The managed.
        /// </value>
        public bool Managed { get; set; }
        #endregion

        #region Auto Numbering Settings
        /// <summary>
        /// Gets or sets the auto numbering settings.
        /// </summary>
        /// <value>
        /// The auto numbering settings.
        /// </value>
        public bool AutoNumberingSettings { get; set; }
        #endregion

        #region Calendar Settings
        /// <summary>
        /// Gets or sets the calendar settings.
        /// </summary>
        /// <value>
        /// The calendar settings.
        /// </value>
        public bool CalendarSettings { get; set; }
        #endregion

        #region Customization Settings
        /// <summary>
        /// Gets or sets the customization settings.
        /// </summary>
        /// <value>
        /// The customization settings.
        /// </value>
        public bool CustomizationSettings { get; set; }
        #endregion

        #region Email Tracking Settings
        /// <summary>
        /// Gets or sets the email tracking settings.
        /// </summary>
        /// <value>
        /// The email tracking settings.
        /// </value>
        public bool EmailTrackingSettings { get; set; }
        #endregion

        #region General Settings
        /// <summary>
        /// Gets or sets the general settings.
        /// </summary>
        /// <value>
        /// The general settings.
        /// </value>
        public bool GeneralSettings { get; set; }
        #endregion

        #region Isv Config
        /// <summary>
        /// Gets or sets the isv config.
        /// </summary>
        /// <value>
        /// The isv config.
        /// </value>
        public bool IsvConfig { get; set; }
        #endregion

        #region Marketing Settings
        /// <summary>
        /// Gets or sets the marketing settings.
        /// </summary>
        /// <value>
        /// The marketing settings.
        /// </value>
        public bool MarketingSettings { get; set; }
        #endregion

        #region Outlook Synchronization Settings
        /// <summary>
        /// Gets or sets the outlook synchronization settings.
        /// </summary>
        /// <value>
        /// The outlook synchronization settings.
        /// </value>
        public bool OutlookSynchronizationSettings { get; set; }
        #endregion

        #region Relationship Roles
        /// <summary>
        /// Gets or sets the relationship roles.
        /// </summary>
        /// <value>
        /// The relationship roles.
        /// </value>
        public bool RelationshipRoles { get; set; }
        #endregion

        #region Publish Workflows
        /// <summary>
        /// Gets or sets the publish workflows.
        /// </summary>
        /// <value>
        /// The publish workflows.
        /// </value>
        public bool PublishWorkflows { get; set; }
        #endregion

        #region Overwrite Unmanaged Customizations
        /// <summary>
        /// Gets or sets the overwrite unmanaged customizations.
        /// </summary>
        /// <value>
        /// The overwrite unmanaged customizations.
        /// </value>
        public bool OverwriteUnmanagedCustomizations { get; set; }
        #endregion

        #region = Constructor =
        /// <summary>
        /// Initializes a new instance of the <see cref="CommandArgs" /> class.
        /// </summary>
        /// <param name="args">The args.</param>
        public CommandArgs(string[] args)
        {
            this.Initialize(args);
        }
        #endregion

        #region Initialize
        /// <summary>
        /// Initializes instance with specified args.
        /// </summary>
        /// <param name="args">The args.</param>
        internal void Initialize(string[] args)
        {
            if (args.Length > 0)
            {
                foreach (var arg in args)
                {
                    if (arg.ToLower().StartsWith(Arguments.OperationArg))
                    {
                        this.Operation = arg.Remove(0, Arguments.OperationArg.Length);
                    }
                    if (arg.ToLower().StartsWith(Arguments.CrmConnectionStringArg))
                    {
                        this.CrmConnectionString = arg.Remove(0, Arguments.CrmConnectionStringArg.Length);
                    }
                    if (arg.ToLower().StartsWith(Arguments.ApplicationLogFilePathArg))
                    {
                        this.ApplicationLogFilePath = arg.Remove(0, Arguments.ApplicationLogFilePathArg.Length);
                    }
                    if (arg.ToLower().StartsWith(Arguments.SolutionNameArg))
                    {
                        this.SolutionName = arg.Remove(0, Arguments.SolutionNameArg.Length);
                    }
                    if (arg.ToLower().StartsWith(Arguments.SolutionFilePathArg))
                    {
                        this.SolutionFilePath = arg.Remove(0, Arguments.SolutionFilePathArg.Length);
                    }
                    if (arg.ToLower().StartsWith(Arguments.LogFilePathArg))
                    {
                        this.LogFilePath = arg.Remove(0, Arguments.LogFilePathArg.Length);
                    }
                    if (arg.ToLower().StartsWith(Arguments.ConfirmPromptArg))
                    {
                        this.ConfirmPrompt = true;
                    }
                    if (arg.ToLower().StartsWith(Arguments.HideHeaderArg))
                    {
                        this.HideHeader = true;
                    }

                    if (arg.ToLower().StartsWith(Arguments.ManagedArg))
                    {
                        this.Managed = true;
                    }
                    if (arg.ToLower().StartsWith(Arguments.AutoNumberingSettingsArg))
                    {
                        this.AutoNumberingSettings = true;
                    }
                    if (arg.ToLower().StartsWith(Arguments.CalendarSettingsArg))
                    {
                        this.CalendarSettings = true;
                    }
                    if (arg.ToLower().StartsWith(Arguments.CustomizationSettingsArg))
                    {
                        this.CustomizationSettings = true;
                    }
                    if (arg.ToLower().StartsWith(Arguments.EmailTrackingSettingsArg))
                    {
                        this.EmailTrackingSettings = true;
                    }
                    if (arg.ToLower().StartsWith(Arguments.GeneralSettingsArg))
                    {
                        this.GeneralSettings = true;
                    }
                    if (arg.ToLower().StartsWith(Arguments.IsvConfigArg))
                    {
                        this.IsvConfig = true;
                    }
                    if (arg.ToLower().StartsWith(Arguments.MarketingSettingsArg))
                    {
                        this.MarketingSettings = true;
                    }
                    if (arg.ToLower().StartsWith(Arguments.OutlookSynchronizationSettingsArg))
                    {
                        this.OutlookSynchronizationSettings = true;
                    }
                    if (arg.ToLower().StartsWith(Arguments.RelationshipRolesArg))
                    {
                        this.RelationshipRoles = true;
                    }
                    if (arg.ToLower().StartsWith(Arguments.PublishWorkflowsArg))
                    {
                        this.PublishWorkflows = true;
                    }
                    if (arg.ToLower().StartsWith(Arguments.OverwriteUnmanagedCustomizationsArg))
                    {
                        this.OverwriteUnmanagedCustomizations = true;
                    }
                    if (arg.ToLower().StartsWith(Arguments.NoPromptArg))
                    {
                        this.NoPrompt = true;
                    }
                }
            }
        }
        #endregion

        #region Is Valid
        /// <summary>
        /// Determines whether this command argument is valid.
        /// </summary>
        /// <returns></returns>
        public Boolean IsValid(out string validationErrorMessage)
        {
            validationErrorMessage = string.Empty;
            if (string.IsNullOrEmpty(this.Operation))
            {
                validationErrorMessage = "operation parameter is missing";
                return false;
            }
            else
            {
                if (string.IsNullOrEmpty(this.CrmConnectionString))
                {
                    validationErrorMessage = "crmconnectionstring parameter is missing";
                    return false;
                }

                if (this.Operation == OperationTypes.Delete)
                {
                    if (string.IsNullOrEmpty(this.SolutionName))
                    {
                        validationErrorMessage = "solutionname parameter is missing";
                        return false;
                    }
                }
                else if (this.Operation == OperationTypes.Export)
                {
                    if (string.IsNullOrEmpty(this.SolutionName))
                    {
                        validationErrorMessage = "solutionname parameter is missing";
                        return false;
                    }

                    if (string.IsNullOrEmpty(this.SolutionFilePath))
                    {
                        validationErrorMessage = "solutionfilepath parameter is missing";
                        return false;
                    }

                    FileInfo fi = new FileInfo(this.SolutionFilePath);
                    var solutionFileDirectoryPath = fi.DirectoryName;

                    if (!Directory.Exists(solutionFileDirectoryPath))
                    {
                        validationErrorMessage = string.Format("solutionfilepath : folder '{0}' does not exist", this.SolutionFilePath);
                        return false;
                    }
                }
                else if (this.Operation == OperationTypes.Import)
                {
                    if (string.IsNullOrEmpty(this.SolutionFilePath))
                    {
                        validationErrorMessage = "solutionfilepath parameter is missing";
                        return false;
                    }
                    if (!File.Exists(this.SolutionFilePath))
                    {
                        validationErrorMessage = string.Format("solutionfilepath : file '{0}' was not found", this.SolutionFilePath);
                        return false;
                    }
                }
                else if (this.Operation == OperationTypes.Publish)
                {
                    // No specific parameters
                }
                else
                {
                    validationErrorMessage = "operation parameter is invalid";
                    return false;
                }
            }

            return true;
        }
        #endregion

        #region Output
        /// <summary>
        /// Outputs specified arguments values.
        /// </summary>
        /// <returns></returns>
        public string Output()
        {
            const string outputFormat = "\t{0} : {1}";
            StringBuilder output = new StringBuilder();
            output.AppendLine("Operation parameters :");
            output.AppendLine(String.Format(outputFormat, Arguments.OperationArg, this.Operation));
            output.AppendLine(String.Format(outputFormat, Arguments.CrmConnectionStringArg, this.CrmConnectionString));

            switch (this.Operation)
            {
                case OperationTypes.Delete:
                    output.AppendLine(String.Format(outputFormat, Arguments.SolutionNameArg, this.SolutionName));
                    break;
                case OperationTypes.Export:
                    output.AppendLine(String.Format(outputFormat, Arguments.SolutionNameArg, this.SolutionName));
                    output.AppendLine(String.Format(outputFormat, Arguments.SolutionFilePathArg, this.SolutionFilePath));

                    output.AppendLine(String.Format(outputFormat, Arguments.ManagedArg, this.Managed));
                    output.AppendLine(String.Format(outputFormat, Arguments.AutoNumberingSettingsArg, this.AutoNumberingSettings));
                    output.AppendLine(String.Format(outputFormat, Arguments.CalendarSettingsArg, this.CalendarSettings));
                    output.AppendLine(String.Format(outputFormat, Arguments.CustomizationSettingsArg, this.CustomizationSettings));
                    output.AppendLine(String.Format(outputFormat, Arguments.EmailTrackingSettingsArg, this.EmailTrackingSettings));
                    output.AppendLine(String.Format(outputFormat, Arguments.GeneralSettingsArg, this.GeneralSettings));
                    output.AppendLine(String.Format(outputFormat, Arguments.IsvConfigArg, this.IsvConfig));
                    output.AppendLine(String.Format(outputFormat, Arguments.MarketingSettingsArg, this.MarketingSettings));
                    output.AppendLine(String.Format(outputFormat, Arguments.OutlookSynchronizationSettingsArg, this.OutlookSynchronizationSettings));
                    output.AppendLine(String.Format(outputFormat, Arguments.RelationshipRolesArg, this.RelationshipRoles));
                    break;
                case OperationTypes.Import:
                    output.AppendLine(String.Format(outputFormat, Arguments.SolutionFilePathArg, this.SolutionFilePath));
                    output.AppendLine(String.Format(outputFormat, Arguments.LogFilePathArg, this.LogFilePath));
                    output.AppendLine(String.Format(outputFormat, Arguments.PublishWorkflowsArg, this.PublishWorkflows));
                    output.AppendLine(String.Format(outputFormat, Arguments.OverwriteUnmanagedCustomizationsArg, this.OverwriteUnmanagedCustomizations));

                    break;
                case OperationTypes.Publish:

                    break;
            }

            return output.ToString();
        }
        #endregion
    }
}
